package com.szu.calculator;

import androidx.appcompat.app.AppCompatActivity;

import android.content.res.Configuration;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import java.util.Stack;

public class MainActivity extends AppCompatActivity {

    //竖屏的View
    Button button_AC;
    Button button_e;
    Button button_mode;
    Button button_divide;
    Button button_multiply;
    Button button_sub;
    Button button_plus;
    Button button_eq;
    Button button_9;
    Button button_8;
    Button button_7;
    Button button_6;
    Button button_5;
    Button button_4;
    Button button_3;
    Button button_2;
    Button button_1;
    Button button_0;
    Button button_dot;
    TextView textview;
    String question="";

    //横屏的view(在竖屏的基础上添加的)
    Button button_sqrt;

    Button button_log;

    Button button_sin;

    Button button_cos;

    String lastquestion="";
    float answer;

    Stack<Float> number=new Stack();//操作数栈

    Stack<Character> op=new Stack();//运算符栈

    int calculatedonetimes=0;
    int textviewlength=0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        int orientation=getResources().getConfiguration().orientation;
        setContentView(R.layout.activity_main);
        if(orientation== Configuration.ORIENTATION_PORTRAIT)
        {
//控件连接
            textview=findViewById(R.id.tv);
            button_AC=findViewById(R.id.AC);
            button_e=findViewById(R.id.bak);
            button_mode=findViewById(R.id.per);
            button_divide=findViewById(R.id.divide);
            button_multiply=findViewById(R.id.multiply);
            button_sub=findViewById(R.id.sub);
            button_plus=findViewById(R.id.plus);
            button_eq=findViewById(R.id.equal);
            button_9=findViewById(R.id.num9);
            button_8=findViewById(R.id.num8);
            button_7=findViewById(R.id.num7);
            button_6=findViewById(R.id.num6);
            button_5=findViewById(R.id.num5);
            button_4=findViewById(R.id.num4);
            button_3=findViewById(R.id.num3);
            button_2=findViewById(R.id.num2);
            button_1=findViewById(R.id.num1);
            button_0=findViewById(R.id.num0);
            button_dot=findViewById(R.id.dot);
            //注册监听器
            button_AC.setOnClickListener(this::onClick);
            button_e.setOnClickListener(this::onClick);
            button_mode.setOnClickListener(this::onClick);
            button_divide.setOnClickListener(this::onClick);
            button_multiply.setOnClickListener(this::onClick);
            button_sub.setOnClickListener(this::onClick);
            button_plus.setOnClickListener(this::onClick);
            button_eq.setOnClickListener(this::onClick);
            button_9.setOnClickListener(this::onClick);
            button_8.setOnClickListener(this::onClick);
            button_7.setOnClickListener(this::onClick);
            button_6.setOnClickListener(this::onClick);
            button_5.setOnClickListener(this::onClick);
            button_4.setOnClickListener(this::onClick);
            button_3.setOnClickListener(this::onClick);
            button_2.setOnClickListener(this::onClick);
            button_1.setOnClickListener(this::onClick);
            button_0.setOnClickListener(this::onClick);
            button_dot.setOnClickListener(this::onClick);
        }
        else if(orientation==Configuration.ORIENTATION_LANDSCAPE)
        {
//控件连接
            textview=findViewById(R.id.tv1);
            button_AC=findViewById(R.id.AC1);
            button_e=findViewById(R.id.bak1);
            button_mode=findViewById(R.id.per1);
            button_divide=findViewById(R.id.divide1);
            button_multiply=findViewById(R.id.multiply1);
            button_sub=findViewById(R.id.sub1);
            button_plus=findViewById(R.id.plus1);
            button_eq=findViewById(R.id.equal1);
            button_9=findViewById(R.id.num91);
            button_8=findViewById(R.id.num81);
            button_7=findViewById(R.id.num71);
            button_6=findViewById(R.id.num61);
            button_5=findViewById(R.id.num51);
            button_4=findViewById(R.id.num41);
            button_3=findViewById(R.id.num31);
            button_2=findViewById(R.id.num21);
            button_1=findViewById(R.id.num11);
            button_0=findViewById(R.id.num01);
            button_dot=findViewById(R.id.dot1);
            //注册监听器
            button_AC.setOnClickListener(this::onClick);
            button_e.setOnClickListener(this::onClick);
            button_mode.setOnClickListener(this::onClick);
            button_divide.setOnClickListener(this::onClick);
            button_multiply.setOnClickListener(this::onClick);
            button_sub.setOnClickListener(this::onClick);
            button_plus.setOnClickListener(this::onClick);
            button_eq.setOnClickListener(this::onClick);
            button_9.setOnClickListener(this::onClick);
            button_8.setOnClickListener(this::onClick);
            button_7.setOnClickListener(this::onClick);
            button_6.setOnClickListener(this::onClick);
            button_5.setOnClickListener(this::onClick);
            button_4.setOnClickListener(this::onClick);
            button_3.setOnClickListener(this::onClick);
            button_2.setOnClickListener(this::onClick);
            button_1.setOnClickListener(this::onClick);
            button_0.setOnClickListener(this::onClick);
            button_dot.setOnClickListener(this::onClick);
        }





    }
    //运算优先级
    char oper[]={'#','-','+','*','/'};

    //得到优先级函数
    int getlevel(char o)
    {
        for (int i = 0; i < 5; i++)
        {
            if (o==oper[i])
            {
                return i;
            }

        }
        return -1;
    }

    //判断是否为纯数字函数
    boolean allisnumber(String question)
    {
        boolean flag=false;
        int i,j;
        for (i=0;i<question.length();i++)
        {
            if (question.charAt(i)>=48&&question.charAt(i)<=57)
            {
                break;
            }
        }
        for (j=question.length()-1;j>=0;j--)
        {
            if (question.charAt(j)<48||question.charAt(j)>57)
            {
                j++;
                break;
            }
        }
        if (j==-1)
        {
            j=0;
        }
        if (i==j)
        {
            flag=true;
        }
        else
        {
            return false;
        }
        return flag;
    }

    //对答案进行调整
    boolean adjustanswer(float a)
    {
        if ((int)a==a)
        {
            answer=(int)a;
            return true;
        }
        else
        {
            return false;
        }
    }


    //计算函数
    public float calculate(String question)
    {
        calculatedonetimes++;//计算次数记录
            //判断是否为空问题
            if (question.isEmpty())//如果输入栏为空就直接显示0
            {
                return 0;
            }
            else if (allisnumber(question))
            {
//                textview.setText("");
//                textview.append(question);
                answer=Float.parseFloat(question);
            }
            else
            {
                float answer;
                op.push('#');//运算符空结束标志
                question+="#";//在尾部加入井号用于计算结束标志

                int qlength=question.length();//问题长度
                float lilnum=0;
                int negaflag=0;
                if (question.charAt(0)=='-')
                {
                    question=question.substring(1,qlength-1);
                    qlength--;
                    negaflag=1;
                }

                for (int i = 0; i < qlength; i++)
                {


                    if (question.charAt(i)==46||question.charAt(i)>=48&&question.charAt(i)<=57)//判断是否为小数点或者数字
                    {
                        if (question.charAt(i)==46)//如果为小数点
                        {
                            if (i==0)//如果为第一个操作数的话需要补0
                            {
                                int k;
                                for (k = 1; k < qlength; k++)
                                {
                                    if (question.charAt(k)>=48&&question.charAt(k)<=57)
                                    {
                                        int singlenum=(int)question.charAt(k)-48;
                                        lilnum+=singlenum/Math.pow(10,k);
                                    }
                                    else
                                    {

                                        break;
                                    }
                                }
                                if (negaflag==1)
                                {
                                    number.push(-lilnum);//负数压入操作数栈
                                    negaflag=0;
                                }
                                else
                                {
                                    number.push(lilnum);//压入操作数栈
                                }

                                lilnum=0;//重置小数
                                i=k-1;//移动光标到处理完毕小数后的下一个操作符
                            }
                            else//如果不是第一个操作数的话需要将前面的数进行合并
                            {
                                int j;
                                int countnum=0;
                                for (j = i-1; j >= 0; j--)
                                {
                                    if (question.charAt(j)>=48&&question.charAt(j)<=57)
                                    {
                                        number.pop();//弹出
                                        lilnum+=((int)question.charAt(j)-48)*Math.pow(10,countnum);
                                        countnum++;
                                    }
                                    else
                                    {
                                        j+=1;
                                        break;
                                    }
                                }
                                if (j==-1)//如果一直弹出直到问题的头部
                                {
                                    j=0;
                                }
                                countnum=1;
                                int k;
                                for (k = i+1; k < qlength; k++)
                                {
                                    if (question.charAt(k)>=48&&question.charAt(k)<=57)
                                    {
                                        int singlenum=(int)question.charAt(k)-48;
                                        lilnum+=singlenum/Math.pow(10,countnum);
                                        countnum++;
                                    }
                                    else
                                    {

                                        break;
                                    }
                                }
                                if (negaflag==1)
                                {
                                    number.push(-lilnum);//负数压入操作数栈
                                    negaflag=0;
                                }
                                else
                                {
                                    number.push(lilnum);//压入操作数栈
                                }
                                lilnum=0;//重置小数
                                i=k-1;//移动光标到处理完毕小数后的下一个操作符



                            }

                        }
                        else
                        {
                            if (i!=0&&question.charAt(i-1)>=48&&question.charAt(i-1)<=57)//说明前面一位是数字，需要进行合并
                            {
                                float newnumber=number.peek()*10+question.charAt(i)-48;
                                number.pop();
                                number.push(newnumber);
                            }
                            else
                            {
                                number.push((float)question.charAt(i)-48);
                            }

                        }
                    }
                    else//为操作符
                    {
                        int toplevel=getlevel(op.peek());//当前栈顶操作符优先级
                        if (toplevel==0&&getlevel(question.charAt(i))==0)//运算结束标志
                        {
                            answer=number.peek();

                        }
                        else
                        {




                            if (getlevel(question.charAt(i))>toplevel)//如果入栈元素优先级大于栈顶元素
                            {
                                op.push(question.charAt(i));
                            }
                            else//否则
                            {
                                while (getlevel(question.charAt(i))<=toplevel&&((toplevel==0&&getlevel(question.charAt(i))!=0)||(toplevel!=0&&getlevel(question.charAt(i))==0)))
                                {
                                    //弹出操作符栈顶元素
                                    op.pop();

                                    //弹出两个操作数,注意，在式子中靠前的数字在栈中位置低于在式子中靠后的数字
                                    float num2=number.peek();
                                    number.pop();
                                    float num1=number.peek();
                                    number.pop();
                                    float finalnum=0;
                                    switch (toplevel)
                                    {
                                        case 1:
                                            finalnum=num1-num2;
                                            break;

                                        case 2:
                                            finalnum=num1+num2;
                                            break;

                                        case 3:
                                            finalnum=num1*num2;
                                            break;

                                        case 4:
                                            finalnum=num1/num2;
                                            break;

                                        default:
                                            break;
                                    }
                                    number.push(finalnum);//得数压入栈中
                                    toplevel=getlevel(op.peek());
                                }
                                op.push(question.charAt(i));

                            }
                        }

                    }
                }


                return number.peek();
            }

        return answer;
    }

int view_id;
    //点击事件函数
    public void onClick(View v)
    {
        if (textviewlength>17)
        {
            textview.setText("");
            Toast.makeText(this,String.format("输入的表达式过长！"),Toast.LENGTH_LONG).show();
            textviewlength=0;
        }
        else {
            view_id=v.getId();
            if(view_id==R.id.AC||view_id==R.id.AC1)
            {
                textview.setText("");
                question = "";
                textviewlength=0;
            }
            else if(view_id==R.id.equal||view_id==R.id.equal1)
            {
                answer = calculate(question);
                textview.setText("");
                if(adjustanswer(answer))
                {
                    textview.append(Integer.toString((int)answer));
                }
                else
                {
                    textview.append(Float.toString(answer));
                }
            }
            else if(view_id==R.id.bak||view_id==R.id.bak1)
            {
                if(textviewlength>=1)
                {
                    lastquestion=question.substring(0,textviewlength-1);
                    textview.setText(lastquestion);
                    question=lastquestion.substring(0);
                    textviewlength--;
                }
                else
                {
                    textview.setText("");

                }
            }
            else if(view_id==R.id.multiply||view_id==R.id.multiply1)
            {
                textview.append("×");

                question += "*";
                textviewlength++;
            }
            else if(view_id==R.id.sub||view_id==R.id.sub1)
            {
                textview.append("-");

                question += "-";
                textviewlength++;
            }
            else if(view_id==R.id.plus||view_id==R.id.plus1)
            {
                textview.append("+");

                question += "+";
                textviewlength++;
            }
            else if(view_id==R.id.num9||view_id==R.id.num91)
            {
                textview.append("9");

                question += "9";
                textviewlength++;
            }
            else if(view_id==R.id.num8||view_id==R.id.num81)
            {
                textview.append("8");

                question += "8";
                textviewlength++;
            }
            else if(view_id==R.id.num7||view_id==R.id.num71)
            {
                textview.append("7");

                question += "7";
                textviewlength++;
            }
            else if(view_id==R.id.num6||view_id==R.id.num61)
            {
                textview.append("6");

                question += "6";
                textviewlength++;
            }
            else if(view_id==R.id.num5||view_id==R.id.num51)
            {
                textview.append("5");

                question += "5";
                textviewlength++;
            }
            else if(view_id==R.id.num4||view_id==R.id.num41)
            {
                textview.append("4");

                question += "4";
                textviewlength++;
            }
            else if(view_id==R.id.num3||view_id==R.id.num31)
            {
                textview.append("3");

                question += "3";
                textviewlength++;
            }
            else if(view_id==R.id.num2||view_id==R.id.num21)
            {
                textview.append("2");

                question += "2";
                textviewlength++;
            }
            else if(view_id==R.id.num1||view_id==R.id.num11)
            {
                textview.append("1");

                question += "1";
                textviewlength++;
            }
            else if(view_id==R.id.num0||view_id==R.id.num01)
            {
                textview.append("0");

                question += "0";
                textviewlength++;
            }
            else if(view_id==R.id.dot||view_id==R.id.dot1)
            {
                textview.append(".");

                question += ".";
                textviewlength++;
            }



        }
    }
}